import "../css/style.css";
import "../css/desert.css";
import "../css/smoothness/jquery-ui-1.8.13.custom.css";

let gl = null;      // WebGL 上下文
let prg = null;     // program 着色器
let c_width = 0;    // canvas的宽
let c_height = 0;   // canvas的高

let part = [];
let vbo = [];
let ibo = [];

let mvMatrix = mat4.create();
let pMatrix = mat4.create();

let angle = 0;

/**
 * 一些操作图形处理器(GPU)的指令
 * 如何处理我们传入的顶点和片元（有关详细信息，请参阅第3章）
 */
function initProgram() {
    let fgShader = utils.getShader(gl, 'shader-fs');
    let vxShader = utils.getShader(gl, 'shader-vs');

    prg = gl.createProgram();
    // 添加一个预先定义的着色器
    gl.attachShader(prg, vxShader);
    gl.attachShader(prg, fgShader);
    gl.linkProgram(prg);

    if (!gl.getProgramParameter(prg, gl.LINK_STATUS)) {
        alert('Could not initialise shaders');
    }

    gl.useProgram(prg);
    //下面代码获取着色器中的uniforms和attributes的引用
    // 这是一个必须的步骤，因为着色器不是用JavaScript编写的，而是用GLSL语言。
    prg.aVertexPosition = gl.getAttribLocation(prg, 'aVertexPosition');
    prg.uPMatrix = gl.getUniformLocation(prg, 'uPMatrix');
    prg.uMVMatrix = gl.getUniformLocation(prg, 'uMVMatrix');
}

function loadModel() {
    for (let i = 1; i < 179; i++) {
        const filename = `../models/nissan_gts/pr${i}.json`;
        loadPart(filename);
    }
}

function loadPart(filename) {
    let request = new XMLHttpRequest();
    console.info(`Requesting ${filename}`);
    request.open('GET', filename);

    request.onreadystatechange = () => {
        if (request.readyState === 4) {
            if (request.status === 404) {
                console.info(`${filename} does not exist.`);
            } else {
                handleLoadedModel(filename, JSON.parse(request.responseText));
            }
        }
    }
    request.send();
}

function handleLoadedModel(filename, payload) {

    console.info(filename + 'has been retrieved from the server');

    let vertexBufferObject = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBufferObject);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(payload.vertices), gl.STATIC_DRAW);
    gl.bindBuffer(gl.ARRAY_BUFFER, null);

    let indexBufferObject = gl.createBuffer();
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBufferObject);
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(payload.indices), gl.STATIC_DRAW);
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);

    vbo.push(vertexBufferObject);
    ibo.push(indexBufferObject);
    part.push(payload);
}


function drawScene() {
    gl.clearColor(0.0, 0.0, 0.0, 1.0);
    gl.enable(gl.DEPTH_TEST);

    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    gl.viewport(0, 0, c_width, c_height);

    mat4.perspective(45, c_width / c_height, 10, 10000.0, pMatrix);
    mat4.identity(mvMatrix);
    mat4.translate(mvMatrix, [0.0, -200.0, -2300.0]);
    mat4.rotate(mvMatrix, 30 * Math.PI / 180, [1, 0, 0]);
    mat4.rotate(mvMatrix, 30 * Math.PI / 180, [0, 1, 0]);

    gl.uniformMatrix4fv(prg.uPMatrix, false, pMatrix);
    gl.uniformMatrix4fv(prg.uMVMatrix, false, mvMatrix);

    for (let i = 0; i < part.length; i++) {
        gl.bindBuffer(gl.ARRAY_BUFFER, vbo[i]);
        gl.vertexAttribPointer(prg.aVertexPosition, 3, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(prg.aVertexPosition);

        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo[i]);
        gl.drawElements(gl.LINES, part[i].indices.length, gl.UNSIGNED_SHORT, 0);
    }
}

function renderLoop() {
    utils.requestAnimFrame(renderLoop);
    drawScene();
}

function runWebGLApp() {
    // console.log('run webgl app');
    gl = utils.getGLContext('canvas-element-id');
    c_width = gl.canvas.width;
    c_height = gl.canvas.height;

    initProgram();

    loadModel();

    renderLoop();
}

runWebGLApp();
